package uk.ac.lkl.lpp.model.ldo;



import javax.swing.event.ChangeListener;

import uk.ac.lkl.common.util.ChangeSupport;
import uk.ac.lkl.common.util.Linkable;

/**
 * The base-class of learning entities.
 * 
 * @author Darren Pearce
 * @version $Revision: 566 $
 * @version $Date: 2008-02-07 09:40:15 +0000 (Thu, 07 Feb 2008) $
 * 
 */
public abstract class LearningEntity implements Linkable {

	/**
     * The title of this instance.
     * 
     * This will tend to be short and is intended for use in labels,
     * etc so as to minimise the amount of screen real-estate used
     * while at the same time being a handle for the user to
     * understand what entity is referred to.
     * 
     */
    private String title;

    /**
     * The description of this instance.
     * 
     * This is intended to be an (in theory) arbitrary length of text
     * describing the entity in as much detail as the user wants. This
     * information will typically be provided when the user
     * double-clicks on an entity label.
     * 
     */
    private String description;

    /**
     * (optional) link to external resource. should be a URL, but not verified. 
     */
	private String link;

    /**
     * The support for <code>ChangeListener</code>s.
     * 
     */
    private ChangeSupport changeSupport;


    /**
     * Create a new instance with the given title and an empty
     * description.
     * 
     * @param title
     *            the title of this entity
     */
    public LearningEntity(String title) {
        this(title, "", null);
    }


    /**
     * Create a new instance with the given title and description.
     * 
     * @param title
     *            the title of this entity
     * @param description
     *            the description of this entity
     * @param link 
     * 			  link to external resource. should be a URL, but not verified.
     */
    public LearningEntity(String title,
            String description, String link) {
        changeSupport = new ChangeSupport(this);
        setTitle(title);
        setDescription(description);
        setLink(link);
    }


    /**
     * Create a new instance with the given title and description.
     * 
     * @param title
     *            the title of this entity
     * @param description
     *            the description of this entity
     */
    public LearningEntity(String title,
            String description) {
    	this (title, description, null);
    }

    /**
     * Get the title of this instance.
     * 
     * @return the title
     * 
     */
    public String getTitle() {
        return title;
    }


    /**
     * Set the title of this instance.
     * 
     * If the title has changed as a result, the change listeners
     * attached to this instance are notified.
     * 
     * @param title
     *            the new title oif this instance
     * 
     */
    public void setTitle(String title) {
        title = title.trim();        
        
        if (title.equals(this.title))
            return;

        this.title = title;
        fireStateChanged();
    }


    /**
     * Get the description of this instance.
     * 
     * @return the description
     * 
     */
    public String getDescription() {
        return description;
    }


    /**
     * Set the description of this instance.
     * 
     * If the description has changed as a result, the change
     * listeners attached to this instance are notified.
     * 
     * @param description
     *            the new description oif this instance
     * 
     */
    public void setDescription(String description) {
    	if (description == null) return;
        description = description.trim();
        
        if (description.equals(this.description))
            return;

        this.description = description;
        fireStateChanged();
    }

    /**
     * (optional) link to external resource. should be a URL, but not verified. 
     */
    public String getLink() {
		return link;
	}


    /**
     * (optional) link to external resource. should be a URL, but not verified. 
     */
	public void setLink(String link) {
		if (link == null) return;
		link = link.trim();
		if (link.equals(this.link)) return;
		this.link = link;
        fireStateChanged();		
	}

    public abstract String getType();


    /**
     * Return a string representation of this instance.
     * 
     * Currently this consists of just the title.
     * 
     */
    public String toString() {
        return title;
    }


    /**
     * Notify the change listeners of a change to this instance.
     * 
     * Sub-classes can use this method to notify listeners of changes
     * to other fields.
     * 
     */
    protected void fireStateChanged() {
        changeSupport.fireStateChanged();
    }


    /**
     * Add a change listener to this instance.
     * 
     * This listener is notified of changes to the title or
     * description of this instance and any further field changes that
     * sub-classes may implement.
     * 
     * @param listener
     *            the listener to add
     * 
     */
    public void addChangeListener(ChangeListener listener) {
        changeSupport.addListener(listener);
    }


    /**
     * Remove the specified change listener.
     * 
     * @param listener
     *            the listener to remove
     * 
     */
    public void removeChangeListener(ChangeListener listener) {
        changeSupport.removeListener(listener);
    }

}
